package com.dayaokeji.rhythmschoolstudent.client.common;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.TextView;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.chad.library.adapter.base.listener.SimpleClickListener;
import com.dayaokeji.rhythmschoolstudent.R;
import com.dayaokeji.rhythmschoolstudent.client.common.base.common.BaseFragment;
import com.dayaokeji.rhythmschoolstudent.utils.ServerCallback;
import com.dayaokeji.rhythmschoolstudent.utils.ToastUtils;
import com.dayaokeji.rhythmschoolstudent.view.RefreshLayout;
import com.dayaokeji.rhythmschoolstudent.wiget.WrapLinearLayoutManager;
import com.dayaokeji.server_api.Page;
import com.dayaokeji.server_api.ServerResponse;
import com.dayaokeji.server_api.domain.Course;
import com.dayaokeji.server_api.domain.Meeting;
import com.orhanobut.logger.Logger;

import java.util.List;

import retrofit2.Call;

/**
 * 通用List
 *
 * @param <ITEM>
 * @param <HOLDER>
 */
public abstract class MultiListFragment<ITEM, HOLDER extends BaseViewHolder> extends BaseFragment implements BaseQuickAdapter.RequestLoadMoreListener, SwipeRefreshLayout.OnRefreshListener, ViewTreeObserver.OnPreDrawListener {

    public static final int DEFAULT_PAGE_SIZE = 15;
    public static final int NO_PAGE = 0;

    private RecyclerView recyclerView;
    private RefreshLayout refreshLayout;
    private View standardEmptyView;
    private TextView emptyTextView;

    private Call call;
    private Call call2;
    private int lastHeight = 0;

    private boolean hasNext1 = true;
    private boolean hasNext2 = true;

    protected abstract Call createCall(int offset, int max);

    protected abstract Call createCall2(int offset, int max);

    public int getPageSize() {
        return DEFAULT_PAGE_SIZE;
    }

    public RecyclerView.LayoutManager getLayoutManager(Context context) {
        return new WrapLinearLayoutManager(context);
    }

    @SuppressWarnings("unchecked")
    public BaseQuickAdapter<ITEM, HOLDER> getAdapter() {
        return recyclerView == null ? null : (BaseQuickAdapter<ITEM, HOLDER>) recyclerView.getAdapter();
    }

    public void setAdapter(BaseQuickAdapter<ITEM, HOLDER> adapter) {
        if (recyclerView != null)
            recyclerView.setAdapter(adapter);
        if (adapter != null && recyclerView != null) {
            if (getPageSize() > 0) adapter.setOnLoadMoreListener(this,recyclerView);
            getDataList(0);
        }
        lastHeight = 0;
    }

    public View getEmptyView() {
        return standardEmptyView;
    }

    public void setEmptyText(CharSequence emptyText) {
        emptyTextView.setText(emptyText);
    }

    public void setEmptyText(@StringRes int emptyTextResId) {
        emptyTextView.setText(emptyTextResId);
    }

    public RecyclerView getRecyclerView() {
        return recyclerView;
    }

    public SwipeRefreshLayout getRefreshLayout() {
        return refreshLayout;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Context context = getContext();
        refreshLayout = new RefreshLayout(context);
        refreshLayout.setId(R.id.refresh_layout);
        refreshLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        refreshLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                refreshLayout.removeOnLayoutChangeListener(this);
                if (refreshLayout.isRefreshing()) {
                    refreshLayout.setRefreshing(false);
                    refreshLayout.setRefreshing(true);
                }
            }
        });

        recyclerView = new RecyclerView(context);
        recyclerView.setId(R.id.recycler_view);
        recyclerView.setLayoutManager(getLayoutManager(context));
        refreshLayout.addView(recyclerView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

        standardEmptyView = inflater.inflate(R.layout.empty_layout, recyclerView, false);
        emptyTextView = (TextView) standardEmptyView.findViewById(R.id.text);

        refreshLayout.setOnRefreshListener(this);

        recyclerView.getViewTreeObserver().addOnPreDrawListener(this);

        return refreshLayout;
    }

    @Nullable
    @Override
    protected View onCreate(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onDestroyView() {
        if (call != null) {
            call.cancel();
            call = null;
        }
        if (call2 != null) {
            call2.cancel();
            call2 = null;
        }
        recyclerView.getViewTreeObserver().removeOnPreDrawListener(this);
        refreshLayout = null;
        recyclerView = null;
        standardEmptyView = null;
        emptyTextView = null;
        super.onDestroyView();
    }

    @Override
    public void onRefresh() {
        getDataList(0);
    }

    @Override
    public void onLoadMoreRequested() {
        getDataList(getAdapter().getData().size());
    }

    @SuppressWarnings("unchecked")
    protected void getDataList(final int offset) {
        if (call != null) call.cancel();
        call = createCall(offset, getPageSize());
        call2 = createCall2(offset, getPageSize());
        if (call == null || call2 == null) {
            return;
        }
        if (refreshLayout != null) {
            if (offset == 0 && !refreshLayout.isRefreshing()) refreshLayout.setRefreshing(true);
        }
        Logger.d("getDataList() start called with: offset = [" + offset + "]");
        final BaseQuickAdapter adapter = getAdapter();
        if (offset == 0) {
            if (adapter != null && adapter.getData() != null) {
                adapter.getData().clear();
            }
        }
        if (hasNext1 || offset == 0) {
            call.enqueue(new ServerCallback() {
                @Override
                public void onResponse(boolean success, ServerResponse response) {
                    Logger.d("onResponse() called with: success = [" + success + "], response = [" + response + "]");
                    if (success) {
                        View emptyView = getEmptyView();
                        if (emptyView != null && adapter.getEmptyView() != emptyView) {
                            adapter.setEmptyView(emptyView);
                        }
                        Object data = response.getBody();
                        if (data instanceof List) {
                            adapter.addData(compareMeetingDataList((List<ITEM>) data));
                        } else if (data instanceof Page) {
                            Page page = (Page) data;
                            if (offset == 0) {
                                adapter.addData(compareMeetingDataList(page.getList()));
                            } else {
                                adapter.addData(compareMeetingDataList(page.getList()));
                                adapter.loadMoreComplete();
                            }
                            hasNext1 = page.isHasNextPage();
                        }
                    } else {
                        ToastUtils.info(response.getHeader().getMessage());
                        if (adapter.isLoading()) adapter.loadMoreFail();
                    }
                    if (refreshLayout != null) refreshLayout.setRefreshing(false);
                }

                @Override
                public void onFailure(Call call, Throwable t) {
                    super.onFailure(call, t);
                    if (adapter != null) {
                        if (adapter.isLoading()) adapter.loadMoreFail();
                    }
                    if (refreshLayout != null) refreshLayout.setRefreshing(false);
                }
            });
        }
        if (hasNext2 || offset == 0) {
            call2.enqueue(new ServerCallback() {
                @Override
                public void onResponse(boolean success, ServerResponse response) {
                    Logger.d("onResponse2() called with: success = [" + success + "], response = [" + response + "]");
                    if (success) {
                        View emptyView = getEmptyView();
                        if (emptyView != null && adapter.getEmptyView() != emptyView) {
                            adapter.setEmptyView(emptyView);
                        }
                        Object data = response.getBody();
                        if (data instanceof List) {
                            adapter.addData(compareMeetingDataList((List<ITEM>) data));
                        } else if (data instanceof Page) {
                            Page page = (Page) data;
                            if (offset == 0) {
                                adapter.addData(compareMeetingDataList(page.getList()));
                            } else {
                                adapter.addData(compareMeetingDataList(page.getList()));
                                adapter.loadMoreComplete();
                            }
                            hasNext2 = page.isHasNextPage();
                        }
                    } else {
                        ToastUtils.info(response.getHeader().getMessage());
                        if (adapter.isLoading()) adapter.loadMoreFail();
                    }
                    if (refreshLayout != null) refreshLayout.setRefreshing(false);
                }

                @Override
                public void onFailure(Call call, Throwable t) {
                    super.onFailure(call, t);
                    if (adapter.isLoading()) adapter.loadMoreFail();
                    if (refreshLayout != null) refreshLayout.setRefreshing(false);
                }
            });
        }


        if (!hasNext1 && !hasNext2) {
            adapter.loadMoreEnd();
        }
    }

    @Override
    public boolean onPreDraw() {
        int height = recyclerView.getHeight();
        BaseQuickAdapter<ITEM, HOLDER> adapter = getAdapter();
        if (height > 0 && height != lastHeight && adapter != null) {
            lastHeight = height;
            height = height - recyclerView.getPaddingTop() - recyclerView.getPaddingBottom();
            if (adapter.getHeaderLayout() != null) height -= adapter.getHeaderLayout().getHeight();
            if (adapter.getFooterLayout() != null) height -= adapter.getFooterLayout().getHeight();
            standardEmptyView.setMinimumHeight(height);
        }
        return true;
    }

    /**
     * 比对数据是否重复
     * @param lists
     * @return
     */
    private List<ITEM> compareMeetingDataList(List<ITEM> lists) {
            for (ITEM list : lists) {
                if (getAdapter() != null) {
                    if (getAdapter().getData() != null) {
                        for (ITEM item : getAdapter().getData()) {
                            if (item instanceof Meeting && list instanceof Meeting) {
                                if (((Meeting) item).getId() == ((Meeting) list).getId()) {
                                    lists.remove(item);
                                }
                            }
                        }
                    }
                }
            }
        return lists;
    }


    public static abstract class SimpleOnItemTouchListener extends SimpleClickListener {

        @Override
        public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
        }

        @Override
        public void onItemLongClick(BaseQuickAdapter adapter, View view, int position) {
        }

        @Override
        public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
        }

        @Override
        public void onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) {
        }
    }

}
